#ifndef _DOUBLES_H_
#define _DOUBLES_H_

#include <ncurses.h>
#include <string>
#include <vector>
#include <memory>
#include <optional>

#include "snake.h"
#include "snake_controller.h"

enum class GameResult {
    ONGOING,
    PLAYER1_WIN,
    PLAYER2_WIN,
    DRAW
};

class doubleGame
{
public:
    doubleGame();
    doubleGame(bool enableFinalFight);  // 添加带鏖战开关的构造函数
    ~doubleGame();
    
    void createInformationBoard();
    void renderInformationBoard() const;

    void createGameBoard();
    void renderGameBoard() const;
    
    void createInstructionBoard();
    void renderInstructionBoard() const;
        
    void loadLeadBoard();
    void updateLeadBoard();
    bool readLeaderBoard();
    bool updateLeaderBoard();
    bool writeLeaderBoard();
    void renderLeaderBoard() const;
    
    void renderBoards() const;
    
    void initializeGame();
    void runGame();
    void renderPoints() const;
    void renderBoost() const;
    void renderReverse() const;
    void renderDifficulty() const;
    
    void createRamdonFood();
    void renderFood() const;
    void renderSnakes() const;
    GameResult checkCollisions();

    void renderSpecialFood() const;
    void createSpecialFood();
    void updateSpecialFood();
    void checkSpecialFoodCollision();
    void updateReverseStates();
    
    void startGame();
    bool renderRestartMenu() const;
    void adjustDelay();
    
    
    void renderTemporaryObstacles() const;
    void updateTemporaryObstacles();
    
    // 暂停相关方法
    void togglePause();
    int renderPauseMenu() const;
    bool isPaused() const;
    
    // 鏖战相关方法
    void checkFinalFight();
    void renderFinalFightMessage() const;
    void renderFinalFightWithFlash() const; 

    void renderTime();

    void renderSkill();


private:
    // We need to have two windows
    // One is for game introduction
    // One is for game mWindows
    int mScreenWidth;
    int mScreenHeight;
    int mGameBoardWidth;
    int mGameBoardHeight;
    const int mInformationHeight = 6;
    const int mInstructionWidth = 18;
    long long trueTotalFrames = 0;
    std::vector<WINDOW *> mWindows;
    
    // Snake information for two players
    const int mInitialSnakeLength = 2;
    const char mSnakeSymbol_1 = '@';
    const char mSnakeSymbol_2 = 'O';
    std::unique_ptr<Snake> mPtrSnake1;  // Player 1
    std::unique_ptr<Snake> mPtrSnake2;  // Player 2
    
    // Food information
    SnakeBody mFood;
    const char mFoodSymbol = '#';

    // Special food information
    SnakeBody mSpecialFood;
    const char mSpecialFoodSymbol = '*';
    bool mSpecialFoodActive = false;
    int mSpecialFoodLifetime = 300;
    int mSpecialFoodTimer = 0;
    bool mSpecialFoodBlink = false;
    int mBlinkCounter = 0;
    const int mBlinkInterval = 15;
    int mFoodCounter = 0;
    const int mSpecialFoodInterval = 5;

    bool mIsReversed1 = false;
    bool mIsReversed2 = false;
    int mReverseTimer1 = 0;
    int mReverseTimer2 = 0;
    const int mReverseDuration = 100;
    
    // Game state
    int mPoints1 = 0;  // Player 1 points
    int mPoints2 = 0;  // Player 2 points
    int mBonusPoints1 = 0;
    int mBonusPoints2 = 0;

    // 添加闪烁相关变量
    bool mReverseBlinkState1 = false;  // 玩家1闪烁状态
    bool mReverseBlinkState2 = false;  // 玩家2闪烁状态
    int mReverseBlinkTimer1 = 0;       // 玩家1闪烁计时器
    int mReverseBlinkTimer2 = 0;       // 玩家2闪烁计时器
    const int mReverseBlinkDuration = 20;  // 闪烁持续时间（帧数）
    const int mBlinkFrequency = 3;     // 闪烁频率（每3帧切换一次）

    // Boost information
    bool mBoost1 = false;
    bool mBoost2 = false;
    int mMoveCounter = 0;
    int mBoostDelay;

    GameResult mGameResult = GameResult::ONGOING;

    std::unique_ptr<SnakeController> mSnakeController;
    
    int mDifficulty = 0;
    int mBaseDelay = 100;
    int mDelay;
    const std::string mRecordBoardFilePath = "record_double.dat";
    std::vector<int> mLeaderBoard;
    const int mNumLeaders = 3;
    const int mBonusScore = 2;
    const float mBonusProbability = 0.3f;
    
    //蛇的技能相关
    const int OBSTACLE_LIFESPAN_FRAMES = 1000; // 障碍物持续1000个游戏帧，（约50秒）
    const int SKILL_COOLDOWN_FRAMES = 1;     // 技能冷却时间为1个游戏帧，即可连续释放

    std::vector<TemporaryObstacle> mTemporaryObstacles; // 存储临时障碍物
    bool mPlayer1SkillActive = false; // P1技能是否激活
    bool mPlayer2SkillActive = false; // P2技能是否激活

    // 输入缓冲
    std::optional<Direction> mPlayer1BufferedDirection;
    std::optional<Direction> mPlayer2BufferedDirection;
    long long mPlayer1LastDropFrame = -1; // P1上次使用技能的帧数
    long long mPlayer2LastDropFrame = -1; // P2上次使用技能的帧数

    long long mFrameCounter = 0;              // 游戏总帧数计数器
    
    // 鏖战相关变量
    bool mIsFinalFight = false;               // 是否进入鏖战模式
    bool mFinalFightTriggered = false;        // 是否已经触发过鏖战
    bool mFinalFightEnabled = false;          // 是否启用鏖战功能
    long long mGameStartFrame = 0;            // 游戏开始时的帧数
    const int mFinalFightDelay = 45 * 20;     // 45秒后进入鏖战 (假设20帧/秒)
    int mFinalFightDisplayCounter = 0;        // 鏖战显示计数器
    const int mFinalFightDisplayDuration = 60; // 显示"FINAL FIGHT"的持续时间
    
    int mSkillCooldownFrames = 600;

    int maxDrop1 = -1;
    int maxDrop2 = -1;
  
    // 暂停相关成员变量
    bool mIsPaused = false;
};

#endif